package com.ecommerce.controller;

import com.ecommerce.dto.QueryTypeAllProductRequestDTO;
import com.ecommerce.product.enums.ProductType;
import com.ecommerce.service.ProductPageQueryPitService;
import com.ecommerce.product.domain.Product;
import com.ecommerce.service.QueryTypeAllProductPitService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.ecommerce.dto.ProductQueryRequestDTO;
import com.ecommerce.dto.ProductQueryResponseDTO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.ecommerce.dto.BusApiResponse;
import com.ecommerce.dto.ProductPageResultDTO;
import com.ecommerce.service.ProductPageQueryOrdinaryService;
import io.swagger.annotations.ApiParam;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.Min;

import java.util.Collections;
import java.util.List;

/**
 * 商品管理控制器
 * <p>
 * 提供商品的增删改查、分类查询、搜索等功能
 * 包含普通分页查询和基于PIT的安全分页查询两种实现
 *
 * @see Product
 * @see ProductPageQueryOrdinaryService
 */
@RestController
@RequestMapping("/api/products")
@RequiredArgsConstructor
@Slf4j
@Api(tags = "商品增删改查与搜索API")
@Validated
public class ProductController {

    /**
     * 普通分页查询服务
     */
    private final ProductPageQueryOrdinaryService productPageQueryOrdinaryService;

    /**
     * 基于PIT的安全分页查询服务
     */
    private final ProductPageQueryPitService productPageQueryPitService;

    /**
     * 全量商品查询服务
     */
    private final QueryTypeAllProductPitService queryTypeAllProductPitService;

    /**
     * 获取商品详情
     *
     * @param id 商品ID
     * @return 包含商品详情的响应实体
     */
    @GetMapping("/get-product-detail/{id}")
    public ResponseEntity<Product> getProductDetail(@PathVariable Long id) {
        Product product = productPageQueryOrdinaryService.getProductDetail(id);
        return ResponseEntity.ok(product);
    }

    /**
     * 按分类分页查询商品，使用普通方式查询，未使用PIT
     * @param categoryId 一级分类ID
     * @param subCategoryId 二级分类ID
     * @param productType 商品类型
     * @param page 页码(从0开始)
     * @param size 每页大小
     * @return 分页商品数据
     */
    @ApiOperation("按分类分页查询商品")
    @GetMapping("/page-query-by-category-ordinary")
    public BusApiResponse<ProductPageResultDTO> pageQueryByCategoryOrdinary(
            @ApiParam(value = "一级分类ID", required = true)
            @RequestParam Long categoryId,

            @ApiParam(value = "二级分类ID", required = false)
            @RequestParam(required = false) Long subCategoryId,

            @ApiParam(value = "商品类型", required = true, example = "ELECTRONICS")
            @RequestParam ProductType productType,

            @ApiParam(value = "页码(从0开始)", defaultValue = "0")
            @RequestParam(defaultValue = "0") @Min(0) int page,

            @ApiParam(value = "每页大小", defaultValue = "10")
            @RequestParam(defaultValue = "10") @Min(1) int size) {

        log.info("按分类查询商品: categoryId={}, subCategoryId={}, productType={}, page={}, size={}",
                categoryId, subCategoryId, productType, page, size);

        ProductPageResultDTO result = productPageQueryOrdinaryService.queryByCategory(
                categoryId, subCategoryId, productType, page, size);

        return BusApiResponse.success(result);
    }

    /**
     * 商品分页搜索，使用普通方式查询，未使用PIT
     * @param keyword 搜索关键词
     * @param productType 商品类型
     * @param page 页码(从0开始)
     * @param size 每页大小
     * @return 分页搜索结果
     */
    @ApiOperation("商品分页搜索")
    @GetMapping("/page-search-ordinary")
    public BusApiResponse<ProductPageResultDTO> pageSearchOrdinary(
            @ApiParam(value = "搜索关键词", required = true)
            @RequestParam String keyword,

            @ApiParam(value = "商品类型", required = true, example = "ELECTRONICS")
            @RequestParam ProductType productType,

            @ApiParam(value = "页码(从0开始)", defaultValue = "0")
            @RequestParam(defaultValue = "0") @Min(0) int page,

            @ApiParam(value = "每页大小", defaultValue = "10")
            @RequestParam(defaultValue = "10") @Min(1) int size) {

        log.info("商品搜索: keyword={}, productType={}, page={}, size={}",
                keyword, productType, page, size);

        ProductPageResultDTO result = productPageQueryOrdinaryService.search(
                keyword, productType, page, size);

        return BusApiResponse.success(result);
    }

    /**
     * 查询指定类型的所有商品，使用PIT和search_after进行深度分页查询商品，汇总后一起返回给调用方
     *
     * @param requestDto 查询条件，包含产品大类、一级类别、二级类别
     * @return 包含商品列表的响应实体
     */
    @PostMapping("/query-type-all-product-use-pit")
    public ResponseEntity<List<Product>> queryTypeAllProductUsePit(
            @RequestBody QueryTypeAllProductRequestDTO requestDto) {
        List<Product> products;
        try {
            products = queryTypeAllProductPitService.queryTypeAllProduct(requestDto);
        } catch (Exception e) {
            log.error("queryTypeAllProduct error", e);
            return  ResponseEntity.ok(Collections.emptyList());
        }
        return ResponseEntity.ok(products);
    }

    /**
     * 分页搜索商品，每次只返回1页数据给前端，使用PIT和search_after。
     * 首次查询：GET /api/products/page-search?productType=ELECTRONICS&pageSize=10
     * 后续分页：GET /api/products/page-search?productType=ELECTRONICS&pitId=xxxxx&searchAfter=[...]
     *
     * @param keyword 搜索关键词
     * @param productType 商品类型
     * @param primaryCategory 一级分类
     * @param secondaryCategory 二级分类
     * @param pageSize 每页大小
     * @param pitId PIT ID
     * @param searchAfter 分页标记
     * @return 分页搜索结果
     */
    @GetMapping("/page-search-use-pit")
    @ApiOperation("分页搜索商品")
    public ProductQueryResponseDTO pageSearchUsePit(
            @RequestParam(required = false) String keyword,
            @RequestParam ProductType productType,
            @RequestParam(required = false) Long primaryCategory,
            @RequestParam(required = false) Long secondaryCategory,
            @RequestParam(required = false) Integer pageSize,
            @RequestParam(required = false) String pitId,
            @RequestParam(required = false) Object[] searchAfter) {

        ProductQueryRequestDTO request = new ProductQueryRequestDTO();
        request.setKeyword(keyword);
        request.setPrimaryCategory(primaryCategory);
        request.setSecondaryCategory(secondaryCategory);
        request.setPageSize(pageSize);
        request.setPitId(pitId);
        request.setSearchAfter(searchAfter);

        return productPageQueryPitService.searchProducts(request, productType);
    }

    /**
     * 释放PIT资源
     * DELETE /api/products/release-pit-resource/xxxxx
     * @param pitId 要释放的PIT ID
     */
    @DeleteMapping("/release-pit-resource/{pitId}")
    @ApiOperation("释放PIT资源")
    public void releasePitResource(@PathVariable String pitId) {
        productPageQueryPitService.closePit(pitId);
    }
}